package com.itheima.log;

import cn.hutool.core.date.DateUtil;
import com.itheima.pojo.LogInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;


@Component
@Aspect
public class LogAspectj {
    @Autowired
    LogUtil logUtil;
    /**
     * @Pointcut : 创建一个切点，方便同一方法的复用。
     *  value属性就是AspectJ表达式，
     */
//    @Pointcut("execution(* com.itheima.controller.*.*(..))")
    @Pointcut("@annotation(com.itheima.log.LogAnno)")
    public void pc(){}

    @Around("pc()")
    public Object  log3(ProceedingJoinPoint pj) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        Signature signature = pj.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method targetMethod = methodSignature.getMethod();
        LogAnno annotation = targetMethod.getAnnotation(LogAnno.class);
        LogInfo logInfo = new LogInfo();
        Object obj = null;
        try {
            String[] values = annotation.value();
            String operating = getArgs( values);
            logInfo.setOperating(operating);

            String ipAddress = logUtil.getIpAddress(request);
            System.out.println("ipAddress = " + ipAddress);
            logInfo.setIpAddress(ipAddress);

            logInfo.setUrl(request.getRequestURL().toString());
            logInfo.setUsername(user.getUsername());
            logInfo.setMethodName(targetMethod.getName());

            Object[] args = pj.getArgs();
            String arg = getArgs(args);
            logInfo.setArgs(arg);
            obj = pj.proceed();
            logInfo.setFlag("成功");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            logInfo.setFlag("失败");
        }finally {
            logInfo.setOperateTime(DateUtil.now());
            logUtil.saveLog(logInfo);
        }
        return obj;
    }

    private String getArgs( Object[] args) throws Exception {
        StringBuffer sb = new StringBuffer();
        if (args != null && args.length != 0) {
            for (int i = 0; i < args.length; i++) {
                if (args[i] != null) {
                    String s = String.valueOf(args[i]);
                    sb.append(s+";");
                }
            }
        }
        return sb.toString();
    }
}
